/*
 * Copyright (c) 2018-2024 北京华恒盛世科技有限公司
 * QUICKPOOL is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *     http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
*/

#ifndef HASH_H
#define HASH_H

#include "list.h"

#define HASH_NUM_ENTS(H) ((H) == NULL ? 0 : (H)->numElements)
/* Hash table is a list whose nodes are the hash elements. */
typedef struct hash_table {
    uint32_t      size;           /* Maximum size of the hash table. */
    uint32_t      numElements;    /* Number of elements in the hash table. */
    LIST_T      **hash;         /* The hash table */
} HASH_TABLE_T;

/* Each hash element has a key, an opaque data structure passed in by the caller. */
typedef struct hash_entity {
    struct hash_entity  *forw;     /* Pointer of forward element. */
    struct hash_entity  *back;     /* Pointer of backward element. */
    char                    *key;      /* Each element has its own key in the hash table. */
    void                    *entity;   /* The entity of the element in the hash table. */
} HASH_ENTITY_T;

/*
 * Iterator, attaches itself to the hash and the function hash_walk
 * iterates through the entire table.
 */
typedef struct hash_walk {
    uint32_t             pos;             /* The position of the hash entity. */
    struct hash_entity  *hashEntity;     /* Pointer of hash entity element. */
    struct hash_table   *hashTable;      /* Pointer of the hash table to walk through. */
} HASH_WALK_T;

/* Declare functions about table handling. */
extern HASH_TABLE_T *gf_hash_make(int size);
extern void  gf_hash_free(HASH_TABLE_T *hash_table, void (*func)(void *));
extern void  *gf_hash_install(HASH_TABLE_T *hash_table, const char *key, void *element);
extern void  *gf_hash_remove(HASH_TABLE_T *hash_table, const char *key);
extern void  *gf_hash_find(HASH_TABLE_T *hash_table, const char *key);
extern void  gf_hash_walk_start(HASH_TABLE_T *hash_table, HASH_WALK_T *walk);
extern void  gf_hash_walk_end(HASH_WALK_T *walk);
extern void  *gf_hash_walk(HASH_WALK_T *walk, char **key);

#endif /* HASH_H */
